; BASCOM CPMIO replacement by S. Kluger
; version 1.11 as of 02/07/84
;
; PURPOSE:
; to enhance the operation of BASCOM compiled programs which
; must by the nature of their environment be non-abortable.
; A program compiled with BASCOM can normally be aborted by
; halting a text display with ^S, and then typing ^C. Since
; console output is handled by the BDOS, the BDOS ^C trap
; will branch to warm boot, and that could be a disaster if
; the program runs in a secure environment with the user
; normally unable to enter CP/M, or where CP/M entry depends
; on various controlled conditions. One example is Dick Lieber's
; SIGNON program for RCPM systems, or for that matter, any
; logon-type program used on RCPM systems.
;
; This CPMIO replacement retains the ^S handling of the
; original, while totally ignoring ^C. Note that the $LSTOT
; implementation has not been changed.
;
; PLUGGING IT IN:
; First, use M80 to assemble this file to make CPMIO.REL.
; Now, if you have Digital Research's LIB.COM, do the following:
; A>REN OLIB.REL=BASLIB.REL
; A>LIB BASLIB=OLIB<CPMIO>
; that's all. How to do it with Microsoft's library manager is
; anyone's guess - I prefer the simplicity of DRI products.
; And a warning... this has not been tested on BASCOM 5.3 with BRUN!
; I suspect there the CP/M character IO routines are contained in
; BRUN rather than BASLIB, in which case conversion would not
; be trivial at all.
;
	extrn	$$optr,$$pout,$$sfwa,$$slwa,$$tout,$ini0
	extrn	$memry,cpment,cpmwrm
;
	public	$init,$ioini,$lptot,$osext,$ttyin,$ttyot,$ttyst
	public	cpmvrn,cpmrea,cpmwri
;
a0197:	nop
	nop
	nop
a019a:	nop
	nop
	nop
cot:	nop
	nop
	nop
cpmvrn:	mov	a,m
cpmrea:	nop
cpmwri:	nop
;
$init:	mov	b,h
	mov	c,l
	lhld	cpment+1
	sphl
	push	b
	lxi	d,0ff00h
	dad	d
	shld	$$slwa
	lhld	$memry
	inx	h
	inx	h
	shld	$$sfwa
	jmp	$ini0
;
; IO initialization. set up jumps to BIOS
; sneaky BASCOM makes sure we call the destinations
; of the BIOS jump table, rather than the jump
; table itself!
;
$ioini:	mvi	a,0c3h
	sta	a0197
	sta	a019a
	sta	cot		;added conout
	lhld	cpmwrm+1
	lxi	d,4
	dad	d
	mov	e,m
	inx	h
	mov	d,m
	xchg
	shld	a0197+1
	xchg
	inx	h
	inx	h
	mov	e,m
	inx	h
	mov	d,m
	xchg
	shld	a019a+1
	xchg
	inx	h
	inx	h
	mov	e,m
	inx	h
	mov	d,m
	xchg
	shld	cot+1		;set up our new conout
	mvi	c,0ch
	call	cpment
	sta	cpmvrn
	ora	a
	lxi	h,1514h
	jz	a014b
	lxi	h,2221h
a014b:	shld	cpmrea
	lxi	h,$$tout
	shld	$$optr
	mvi	m,1
	inx	h
	mvi	m,50h
	mvi	a,84h
	sta	$$pout+1
	mvi	a,1
	sta	$$pout
	mvi	a,0ffh
	sta	$$pout-1
	ret
;
$ttyst:	push	b
	push	d
	push	h
	call	a0197
	ora	a
	jmp	a0190
;
$ttyin:	push	b
	push	d
	push	h
	call	a019a
	jmp	a0190
;
; The $ttyout routine used to go through the BDOS,
; which gives RCPM operators headaches. We use BIOS
; output here, but still implement the ^S check
; (but without warmboot at ^S^C)
;
$ttyot:	push	b
	push	d
	push	h
	mov	c,a
	call	cot
	push	psw		;save byte
	call	$ttyst
	jz	none
	call	$ttyin		;get the waiting char
	cpi	'S'-40h		;is it ^S?
	jnz	none		;nope - ignore it
	call	$ttyin		;wait for a response
none:	pop	psw
	jmp	a0190
;
$lptot:	push	b
	lxi	b,0ff05h
a0187:	push	d
	push	h
	push	psw
	ana	b
	mov	e,a
	call	cpment
	pop	psw
a0190:	pop	h
	pop	d
	pop	b
	ret
;
$osext:	jmp	cpmwrm
;
	end
